package com.vincent.template.config;

import com.vincent.template.commons.base.BaseResultDto;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @Author Vincent Wang
 * @Date 2020/10/16 16:19
 */
@RestControllerAdvice(basePackages = "com.vincent.template.controller")
public class Vct520ResponseAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterClass) {
        Method method = Objects.requireNonNull(methodParameter.getMethod());
        // 类上添加的@DisableResponseAdvice注解
        DisableResponseAdvice classDisable =
                method.getDeclaringClass().getAnnotation(DisableResponseAdvice.class);
        // 方法上添加的@DisableResponseAdvice注解
        DisableResponseAdvice methodDisable =
                method.getAnnotation(DisableResponseAdvice.class);
        // 只有两者都没有添加@DisableResponseAdvice注解，才对方法的返回值进行包装
        return classDisable == null && methodDisable == null;
    }

    @Override
    public Object beforeBodyWrite(Object object, MethodParameter methodParameter, MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> converterClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        if (object == null) {
            return BaseResultDto.success(null);
        }
        if (object instanceof String || object instanceof BaseResultDto) {
            return object;
        }
        if (object instanceof Vct520ExceptionHandler.ExceptionError) {
            Vct520ExceptionHandler.ExceptionError error = (Vct520ExceptionHandler.ExceptionError) object;
            return BaseResultDto.fail(error.getMessage());
        }
        return BaseResultDto.success(object);
    }
}
